Snake.prototype = new SceneEditor();  
Snake.prototype.constructor=Snake;

function Snake(scene){
	this.scene = scene;
	this.offsetLeft = 0;
	this.offsetRight = 0;
	this.offsetTop = 0;
	this.offsetBottom = 0;
	this.cellSize = 5;
	
	this.level = null;
	
	this.speed = 8;
	
	this.direction = "left";
	
	this.drawGridLines = true;
	
	this.initialize = function(levelName){
		this.stopMoving();
		levelName = levelName?levelName:"Default";
		this.goodie = null;
		this.scene.clear();
		
		this.updateData();
		
		if(this.drawGridLines) this.drawGrid();
		
		this.initializeLevel(levelName);
	}
		
	
	this.levels = new Array();
	
	this.segments = new Array();
	
	/*this.getLevelWalls : function(levelIndex){
		for(var i=0;i<this.levels.length;i++){
			if(this.leves
		}
		var shapes = [new ResponsiveIrregularShape([{"x":5,"y":5},{"x":5,"y":95},{"x":95,"y":95},{"x":95,"y":90},{"x":10,"y":90},{"x":10,"y":10},{"x":90,"y":10},{"x":90,"y":90},{"x":95,"y":90},{"x":95,"y":5}])];
	}*/
	
	this.initializeLevel = function(levelName){
		this.level = null;
		// init snake
		if(!this.levels || this.levels.length==0){
			this.levels = new Array();
			// initialize game levels
			// init static levels
			var level = {
				name : "Default",
				walls : [],
			};
			this.levels.push(level);
			var level = {
				name : "External Walls",
				walls : [new ResponsiveIrregularShape([{"x":0,"y":0},{"x":0,"y":100},{"x":5,"y":100},{"x":5,"y":0}]),new ResponsiveIrregularShape([{"x":5,"y":100},{"x":100,"y":100},{"x":100,"y":95},{"x":5,"y":95}]),new ResponsiveIrregularShape([{"x":5,"y":0},{"x":100,"y":0},{"x":100,"y":5},{"x":5,"y":5}]),new ResponsiveIrregularShape([{"x":95,"y":5},{"x":95,"y":95},{"x":100,"y":95},{"x":100,"y":5}])],
			};
			this.levels.push(level);
			var level = {
				name : "External and internal walls",
				walls : [new ResponsiveIrregularShape([{"x":0,"y":0},{"x":100,"y":0},{"x":100,"y":100},{"x":0,"y":100},{"x":0,"y":95},{"x":95,"y":95},{"x":95,"y":5},{"x":5,"y":5},{"x":5,"y":95},{"x":0,"y":95}]),new ResponsiveIrregularShape([{"x":20,"y":20},{"x":20,"y":80},{"x":35,"y":80},{"x":35,"y":20}]),new ResponsiveIrregularShape([{"x":80,"y":20},{"x":80,"y":80},{"x":65,"y":80},{"x":65,"y":20}])],
			}
			this.levels.push(level);
		}
		
		// search current level
		for(var i=0;i<this.levels.length;i++){
			var level = this.levels[i];
			if(level.name==levelName){
				this.level = level;
				break;
			}
		}
		
		// init walls
		
		if(this.level){
			for(var i=0;i<this.level.walls.length;i++){
				this.level.walls[i].fillColor = "#0A1F33";
				this.level.walls[i].strokeWidth=0;
				this.level.walls[i].fill =true;
				this.scene.add(this.level.walls[i]);
			}
		}
		
		// init snake segments
		this.segments = new Array();
		for(var i=9;i>3;i--){
			var segment = new SnakeSegment(this, 3,i,this.segments.length==0);
			this.segments.push(segment);
			this.scene.add(segment);					
		}		
		
		this.scene.invalidate();
	}
		
	this.move = function(type){
		var firstSegment = this.segments[0];
		var secondSegment = this.segments[1];
		
		var nextRow = firstSegment.row;
		var nextCol = firstSegment.col;
		if(this.checkAlive(nextRow,nextCol)){
		
			if(type=="up"){
				nextRow = firstSegment.row-1;
				nextCol = firstSegment.col;
			}
			if(type=="down"){
				nextRow = firstSegment.row+1;
				nextCol = firstSegment.col;
			}
			if(type=="left"){
				nextRow = firstSegment.row;
				nextCol = firstSegment.col-1;
			}
			if(type=="right"){
				nextRow = firstSegment.row;
				nextCol = firstSegment.col+1;
			}		
			// check not going backwards
			if(secondSegment.row==nextRow && secondSegment.col==nextCol){
				return false;
			}
			// check hit margins
			if(nextRow<0)nextRow = this.totalRows-1;
			if(nextRow>=this.totalRows)nextRow = 0;
			
			if(nextCol<0)nextCol = this.totalColumns-1;
			if(nextCol>=this.totalColumns)nextCol = 0;
		
		
			var newSegment = null;
			if(this.checkGoodie(nextRow,nextCol)){
				newSegment = new SnakeSegment(this, this.segments[this.segments.length-1].row,this.segments[this.segments.length-1].col);
				newSegment.refreshSegment();
			}
			for(var i=this.segments.length-1;i>0;i--){
				this.segments[i].row = this.segments[i-1].row;
				this.segments[i].col = this.segments[i-1].col;
				this.segments[i].refreshSegment();
			}
			firstSegment.row = nextRow;
			firstSegment.col = nextCol;		
			firstSegment.refreshSegment();

			if(newSegment){
				this.addGoodie();
				this.segments.push(newSegment);
				this.scene.add(newSegment);
			}
			
			 /*for(var i=this.segments.length-1;i>=0;i--){
				 this.segments[i].invalidate();
			 }*/
			 this.scene.invalidate();
		}
		else {
			alert("You are dead");
			this.stopMoving();
			this.initialize(this.level.name);
		}
	}	
	
	this.checkGoodie = function(row, col){
		// check if snake hit itself				
		return this.goodie && this.goodie.col == col && this.goodie.row==row;
	}
	
	this.checkAlive = function(row, col, checkAll){
		// check if snake hit itself
		var st = 3;
		if(checkAll) st = 0;
		for(var i=st;i<this.segments.length;i++){
			if(this.segments[i].row == row && this.segments[i].col==col){
				return false;
			}
		}
		
		// check walls
		if(this.level.walls && this.level.walls.length>0){
			for(var i=0;i<this.level.walls.length;i++){
				if(this.level.walls[i].intersectsBoundary(this.scene,this.segments[0].boundary)){
					return false;
				}
			}
		}
		
		return true;
	}
	
	this.checkGoodiePosition = function(row, col){
		// check if snake is hit
		for(var i=0;i<this.segments.length;i++){
			if(this.segments[i].row == row && this.segments[i].col==col){
				return false;
			}
		}
		
		// compute real pos 
		var sceneSize = this.scene.getSize();
		var pos = {x:col*this.cellWidth+this.offsetLeft,y:row*this.cellHeight+this.offsetTop, w:this.cellWidth, h:this.cellHeight};
		pos = {x:pos.x*sceneSize.w/100,y:pos.y*sceneSize.h/100,w:pos.w*sceneSize.w/100,h:pos.h*sceneSize.h/100};
		// check walls
		if(this.level.walls && this.level.walls.length>0){
			for(var i=0;i<this.level.walls.length;i++){
				if(this.level.walls[i].intersectsBoundary(this.scene, pos)){
					return false;
				}
			}
		}		
		return true;
	}
	
	this.mode = 0;
	this.moving = false;	
	this.start = function(){
		var self = this;
		this.scene.domUtils.addEventSimple(window, "keydown", function(e){
			var evt=(e)?e:(window.event)?window.event:null;
			if(evt){
				var key=(evt.charCode)?evt.charCode:((evt.keyCode)?evt.keyCode:((evt.which)?evt.which:0));				
				if(key==37)self.direction="left";
				if(key==38)self.direction="up";
				if(key==39)self.direction="right";
				if(key==40)self.direction="down";
				if(self.mode==1){
					self.move(self.direction);
				}
				else{
					if(!self.moving){
						// snake not started.. start it
						self.moving = true;
						self.startMoving();
					}
				}
			}			
		});				
	}
	this.interval = null;
	this.startMoving = function(){		
		var self = this;
		this.addGoodie();
		this.interval = setInterval(function(){
			self.move(self.direction);
		},1000/self.speed);		
	}
	this.stopMoving = function(){
		this.moving = false;
		clearInterval(this.interval);
	}
	
	this.goodie = null;
	this.addGoodie = function(){
		if(this.goodie==null)
		{
			this.goodie = new SnakeSegment(this,-1,-1,false);
			this.goodie.fillColor = "#802828";
			this.goodie.strokeColor = "#802828";
			this.scene.add(this.goodie);
		}
		var good = false;
		var row=-1;
		var col=-1;
		while(!good){
			row = Math.floor((Math.random() * this.totalRows-1) + 1);
			col = Math.floor((Math.random() * this.totalColumns-1) + 1);
			good = this.checkGoodiePosition(row,col);
		}
		this.goodie.row = row;
		this.goodie.col = col;	
		this.goodie.refreshSegment();		
	}
}

SnakeSegment.prototype = new ResponsiveRectangle();  
SnakeSegment.prototype.constructor=SnakeSegment;
function SnakeSegment(snake, row, col, isHead){
	this.snake = snake;
	this.row = row;
	this.col = col;
	this.strokeColor = null;
	this.fillColor = "gray";
	this.fill =true;
	this.strokeWidth=0;
	this.isHead = isHead;
	if(isHead){
		this.fillColor = "blue";
	}
	this.refreshSegment = function(){
		if(this.snake){
			this.percentagePosition.x = this.snake.offsetLeft + this.col * this.snake.cellWidth+1;
			this.percentagePosition.y = this.snake.offsetTop + this.row * this.snake.cellHeight+1;
			this.percentagePosition.w = this.snake.cellWidth-2;
			this.percentagePosition.h = this.snake.cellHeight-2;
			this.updateRectangle();
		}
	}
	this.addedToScene = function(scene){		
		this.refreshSegment();		
	}	
}